#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <LittleFS.h> // 包含LittleFS库
ESP8266WebServer esp8266_server(80);
IPAddress local_IP(192, 168, 1, 12);
IPAddress local_IP_AP(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);


String makeResponse(const String &buttonText = "开灯", int refreshTime = 3600) {
  String htmlCode;
  htmlCode += "<!DOCTYPE html> <html>\n";
  htmlCode += "<head>\n";
  htmlCode += "<meta charset=\"UTF-8\">\n";
  htmlCode += "<title>艾莉点灯</title>\n";
  htmlCode += "<style>\n";
  htmlCode += "body {\n";
  htmlCode += "  font-family: Arial, sans-serif;\n";
  htmlCode += "  text-align: center;\n";
  htmlCode += "  margin-top: 50px;\n";
  htmlCode += "  background-image: url('http://hbimg.huaban.com/2de61f00bca7f42f1c33717b4b7d3cada02703af14241a-5mRAbP');\n";
  htmlCode += "  background-size: cover;\n";        // 调整为 contain，确保图片完整显示
  htmlCode += "  background-attachment: fixed;\n";  // 背景图片固定不动
  htmlCode += "  background-repeat: no-repeat;\n";
  htmlCode += "  background-position: center center;\n";  // 明确水平和垂直方向都居中
  htmlCode += "}\n";
  htmlCode += "h1 {\n";
  htmlCode += "  color: #FFB6C1;\n";
  htmlCode += "  font-size: 24px;\n";
  htmlCode += "  padding: 10px 20px;\n";
  htmlCode += "  margin-top: 20px;\n";
  htmlCode += "}\n";
  htmlCode += "</style>\n";
  htmlCode += "</head>\n";
  htmlCode += "<body><h1>艾莉点灯</h1>\n";
  htmlCode += "<form action=\"/LED\" method=\"POST\">\n";
  htmlCode += "<button type=\"submit\">";
  htmlCode += buttonText;
  htmlCode += "</button>\n";
  htmlCode += "</form>\n";
  htmlCode += "<script>\n";
  htmlCode += "setTimeout(function() { window.location.reload(); }, " + String(refreshTime * 1000) + ");\n";
  htmlCode += "</script>\n";
  htmlCode += "</body>\n";
  htmlCode += "</html>\n";
  return htmlCode;
}


void blinkLED(int pin, int times) {
  pinMode(pin, OUTPUT);
  for (int i = 0; i < times; i++) {
    digitalWrite(pin, LOW);
    delay(100);
    digitalWrite(pin, HIGH);
    delay(100);
  }
}

void setup() {
  Serial.begin(9600);
  pinMode(0, OUTPUT);
  digitalWrite(0, HIGH);
  pinMode(2, OUTPUT);
  digitalWrite(2, HIGH);
  delay(1000);
  Serial.println("Starting");
  if (!LittleFS.begin()) {
    Serial.println("打开LittleFS错误");
  } 
  else
   {
    Serial.println("LittleFS 已启动");
    readWiFiData();
    delay(1000);
    readLocalID();
   WiFi.config(local_IP, gateway, subnet);
  }

  // 连接WiFi
  connectWiFi();
}

void loop() {
  esp8266_server.handleClient();
}

void connectWiFi() {
  int timeout = 3;
  int i = 1;
  while (i <= timeout) {
    if (WiFi.status() == WL_CONNECTED) {
      setup_server();
      break;
    }
    delay(50);
    Serial.print("connecting...");  
    Serial.print(i++);
    Serial.println();
  }
  if (i > timeout) {
    Serial.println("WiFi connect timeout");
    startAPMode();
  }
}

void setup_server() {
  Serial.println('\n');
  Serial.print("Connected to ");
  Serial.println(WiFi.SSID());
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());
  esp8266_server.begin();
  esp8266_server.on("/", handleRoot);
  esp8266_server.on("/LED", HTTP_POST, handleLED);
  esp8266_server.onNotFound(handleNotFound);
  Serial.println("HTTP esp8266_server started");
}

void handleRoot() {
  bool led_state = digitalRead(2);
  String buttonText = led_state ? "开灯" : "关灯";
  esp8266_server.send(200, "text/html; charset=UTF-8", makeResponse(buttonText));
  Serial.println("New Web access");
}

void handleLED() {
  Serial.println("LED SET");
  digitalWrite(0, !digitalRead(0));            // 改变LED的点亮或者熄灭状态
  digitalWrite(2, !digitalRead(2));            // 改变LED的点亮或者熄灭状态
  esp8266_server.sendHeader("Location", "/");  // 跳转回页面根目录
  esp8266_server.send(303);                    // 发送Http相应代码303 跳转
}

void handleNotFound() {
  esp8266_server.send(404, "text/plain", "404: Not found");
}

void startAPMode() {
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(local_IP_AP, gateway, subnet);
  WiFi.softAP("ESP8266-AP");
  esp8266_server.on("/", HTTP_GET, handleAPConfig);
  esp8266_server.on("/updateAP", HTTP_POST, handleUpdateAP);
  esp8266_server.begin();
  Serial.println("AP mode started");
}

void readWiFiData() {
  File file = LittleFS.open("/WiFi_data.txt", "r");
  if (!file) {
    Serial.println("无法打开文件 /WiFi_data.txt");
    return;
  }
  while (file.available()) {
    String line = file.readStringUntil('\n');
    int delimiterIndex = line.indexOf(':');
    if (delimiterIndex != -1) {
      String ssid = line.substring(0, delimiterIndex);
      String password = line.substring(delimiterIndex + 1);
       Serial.println("从文件中读取到ssid:");
       Serial.println(ssid);
      Serial.println("密码:");
       Serial.println(password);
       
      WiFi.begin(ssid.c_str(), password.c_str()); 
      if (WiFi.status() == WL_CONNECTED)
      {return;}
      
    }
  }
  file.close();
}

void readLocalID() {
  File file3 = LittleFS.open("/22.txt", "r");
  // if (!file3) {
  //   Serial.println("无法打开文件 /22.txt");
  //   return;
  // }
  while (file3.available()) {
        Serial.println("尝试不判断直接读取localID");
    local_IP.fromString(file3.readString());
  }
  file3.close();
}

void handleAPConfig() {
  String htmlCode = APConfigPage();
  esp8266_server.send(200, "text/html; charset=UTF-8", htmlCode);
}

String APConfigPage() {
  String htmlCode;
  htmlCode += "<!DOCTYPE html> <html><head><title>AP Configuration</title></head><body>";
  htmlCode += "<h1>AP Configuration</h1>";
  htmlCode += "<form method='POST' action='/updateAP'>";
  htmlCode += "<label for='ssid'>SSID:</label><br>";
  htmlCode += "<input type='text' id='ssid' name='ssid' required><br>";
  htmlCode += "<label for='password'>Password:</label><br>";
  htmlCode += "<input type='password' id='password' name='password' required><br>";
  htmlCode += "<label for='ip'>IP Address:</label><br>";
  htmlCode += "<input type='text' id='ip' name='ip' placeholder='192.168.1.x' required><br>";
  htmlCode += "<input type='submit' value='Submit'>";
  htmlCode += "</form></body></html>";
  return htmlCode;
}

void handleUpdateAP() {
  String ssid = esp8266_server.arg("ssid");
  String password = esp8266_server.arg("password");
  String ip = esp8266_server.arg("ip");

  // 更新静态IP
  local_IP.fromString(ip);
  // 将数据追加到WiFi_data.txt
  File file = LittleFS.open("/WiFi_data.txt", "a");
  if (!file) {
    Serial.println("无法打开文件 /WiFi_data.txt for writing");
    return;
  }
  file.println(ssid + ":" + password);
  file.close();

File file2 = LittleFS.open("22.txt", "w");
  if (!file2) {
    Serial.println("无法打开文件 /22.txt for writing");
    return;
  }
  file2.println(ip);
  file2.close();

  WiFi.mode(WIFI_STA);
  Serial.println("AP mode stopped");
  Serial.println(ssid.c_str());
  Serial.println(password.c_str());
  Serial.println(ip.c_str());
  WiFi.begin(ssid.c_str(), password.c_str());


  // 尝试连接WiFi
  int i = 1;
  int timeout = 3;
  while (i <= timeout) {
    if (WiFi.status() == WL_CONNECTED) {
      blinkLED(2, 5); // 闪烁LED
      WiFi.config(local_IP, gateway, subnet);
      setup_server();
      break;
    }
    delay(50);
    Serial.print("connecting...");  
    Serial.print(i++);
    Serial.println();
  }
  if (i > timeout) {
    Serial.println("WiFi connect timeout");
    digitalWrite(2, LOW); // 常亮LED
  }
}